/// MVVM architecture base classes and utilities.
/// MVVM 架构基础类和工具
///
/// Provides ViewModel base class, MVVM widgets, and supporting utilities
/// for implementing the MVVM pattern in Flutter applications.
/// 提供 ViewModel 基类、MVVM 组件和支持工具，用于在 Flutter 应用中实现 MVVM 模式。
///
/// Author: sunlunchang
library;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../code/value_wrapper.dart';

/// Mixin providing MVVM delegation functionality.
/// 提供 MVVM 委托功能的混入
///
/// This mixin connects Views with ViewModels through Provider.
/// 此混入通过 Provider 连接视图和 ViewModel。
mixin MvvmDelegate<T> {
  /// Value wrapper for storing ViewModel instance
  /// 用于存储 ViewModel 实例的值包装器
  final ValueWrap<T> valueWrap = ValueWrap();

  /// Gets the ViewModel instance.
  /// 获取 ViewModel 实例
  ///
  /// Throws [Exception] if ViewModel data is null.
  /// 如果 ViewModel 数据为 null，则抛出异常。
  /// Returns the stored ViewModel instance.
  /// 返回存储的 ViewModel 实例。
  T getVm() {
    final data = valueWrap.getData();
    if (data == null) {
      throw Exception('ViewModel data is null');
    }
    return data;
  }

  /// Registers event handling with ViewModel from Provider.
  /// 从 Provider 注册 ViewModel 的事件处理
  ///
  /// [context] Build context for accessing Provider / 用于访问 Provider 的构建上下文
  /// [listen] Whether to listen to ViewModel changes (default: false) / 是否监听 ViewModel 变化（默认：false）
  ///
  /// Throws [Exception] if Provider<T> is not found in context.
  /// 如果在上下文中找不到 Provider<T>，则抛出异常。
  void registerEvent(BuildContext context, {bool listen = false}) {
    final vm = Provider.of<T>(context, listen: listen);
    if (vm == null) {
      throw Exception('Provider<T> not found in context');
    }
    valueWrap.data = vm;
    onRegisterEventByVm(context, getVm());
  }

  /// Callback for registering events with ViewModel.
  /// 用于注册 ViewModel 事件的回调
  ///
  /// Subclasses can override this method to handle specific registration logic.
  /// 子类可以重写此方法以处理特定的注册逻辑。
  ///
  /// [context] Build context / 构建上下文
  /// [vm] The ViewModel instance / ViewModel 实例
  void onRegisterEventByVm(BuildContext context, T vm) {}
}

/// Abstract base class for MVVM stateless widgets.
/// MVVM 无状态组件的抽象基类
///
/// Extends [StatelessWidget] and mixes in [MvvmDelegate] to provide
/// MVVM functionality to stateless widgets.
/// 扩展 [StatelessWidget] 并混入 [MvvmDelegate] 以为无状态组件提供 MVVM 功能。
///
/// Type parameter [T] must extend [BaseVm].
/// 类型参数 [T] 必须扩展 [BaseVm]。
abstract class MvvmStatelessWidget<T extends BaseVm> extends StatelessWidget
    with MvvmDelegate<T> {
  /// Creates an MVVM stateless widget.
  /// 创建 MVVM 无状态组件
  ///
  /// [key] Optional widget key / 可选的组件键
  MvvmStatelessWidget({Key? key}) : super(key: key);
}

/// Abstract base class for MVVM stateful widget states.
/// MVVM 有状态组件状态的抽象基类
///
/// Extends [State] and mixes in [MvvmDelegate] to provide
/// MVVM functionality to stateful widgets.
/// 扩展 [State] 并混入 [MvvmDelegate] 以为有状态组件提供 MVVM 功能。
///
/// Type parameters / 类型参数:
/// * [W] - The stateful widget type / 有状态组件类型
/// * [T] - The ViewModel type (must extend [BaseVm]) / ViewModel 类型（必须扩展 [BaseVm]）
abstract class MvvmState<W extends StatefulWidget, T extends BaseVm>
    extends State<W> with MvvmDelegate<T> {}

/// Enhanced [ChangeNotifier] with disposal safety.
/// 具有销毁安全性的增强型 [ChangeNotifier]
///
/// Prevents notifying listeners after disposal to avoid errors.
/// 防止在销毁后通知监听器以避免错误。
class AbsoluteChangeNotifier extends ChangeNotifier {
  /// Whether this notifier has been disposed / 此通知器是否已被销毁
  bool _disposed = false;

  /// Gets the disposal status / 获取销毁状态
  bool get disposed => _disposed;

  /// Disposes the notifier and marks it as disposed.
  /// 销毁通知器并将其标记为已销毁
  @override
  void dispose() {
    super.dispose();
    _disposed = true;
  }

  /// Notifies listeners only if not disposed.
  /// 仅在未销毁时通知监听器
  ///
  /// This prevents errors when trying to notify listeners after disposal.
  /// 这可以防止在销毁后尝试通知监听器时出现错误。
  @override
  void notifyListeners() {
    if (!disposed) {
      super.notifyListeners();
    }
  }
}

/// Base ViewModel class for MVVM architecture.
/// MVVM 架构的基础 ViewModel 类
///
/// Extends [AbsoluteChangeNotifier] to provide safe state notification.
/// Supports registering sub-modules ([VmSub]) for decoupling business logic.
/// 扩展 [AbsoluteChangeNotifier] 以提供安全的状态通知。
/// 支持注册子模块 ([VmSub]) 以解耦业务逻辑。
///
/// Author: sunlunchang
class BaseVm extends AbsoluteChangeNotifier {
  /// List of registered ViewModel sub-modules / 已注册的 ViewModel 子模块列表
  final List<VmSub> vmSubList = List.empty(growable: true);

  /// Creates a base ViewModel / 创建基础 ViewModel
  BaseVm();

  /// Registers a ViewModel sub-module.
  /// 注册 ViewModel 子模块
  ///
  /// [vmSub] The sub-module to register / 要注册的子模块
  ///
  /// If [vmSub] is null or already registered, this method does nothing.
  /// 如果 [vmSub] 为 null 或已注册，则此方法不执行任何操作。
  void registerVmSub(VmSub? vmSub) {
    if (vmSub != null && !vmSubList.contains(vmSub)) {
      vmSub.setOwnerVm(this);
      vmSubList.add(vmSub);
    }
  }

  /// Unregisters a ViewModel sub-module.
  /// 注销 ViewModel 子模块
  ///
  /// [vmSub] The sub-module to unregister / 要注销的子模块
  ///
  /// If [vmSub] is null, this method does nothing.
  /// 如果 [vmSub] 为 null，则此方法不执行任何操作。
  void unRegisterVmSub(VmSub? vmSub) {
    if (vmSub != null) {
      vmSubList.remove(vmSub);
      vmSub.onCleared();
    }
  }

  /// Disposes the ViewModel and all registered sub-modules.
  /// 销毁 ViewModel 和所有已注册的子模块
  @override
  void dispose() {
    for (final vmSub in vmSubList) {
      vmSub.onCleared();
    }
    vmSubList.clear();
    super.dispose();
  }
}

/// ViewModel sub-module for decoupling business logic.
/// 用于解耦业务逻辑的 ViewModel 子模块
///
/// VmSub allows extracting common business logic from ViewModels
/// while maintaining a parent-child relationship with the owning ViewModel.
/// The parent ViewModel manages the lifecycle of its VmSub instances.
/// VmSub 允许从 ViewModel 中提取通用业务逻辑，同时保持与所属 ViewModel 的父子关系。
/// 父 ViewModel 管理其 VmSub 实例的生命周期。
class VmSub {
  /// The owning ViewModel / 所属的 ViewModel
  BaseVm? _ownerVm;

  /// Creates a ViewModel sub-module / 创建 ViewModel 子模块
  VmSub();

  /// Sets the owner ViewModel.
  /// 设置所属的 ViewModel
  ///
  /// [ownerVm] The ViewModel that owns this sub-module / 拥有此子模块的 ViewModel
  void setOwnerVm(BaseVm ownerVm) {
    _ownerVm = ownerVm;
  }

  /// Gets the owner ViewModel.
  /// 获取所属的 ViewModel
  ///
  /// Throws [Exception] if owner ViewModel is not registered.
  /// 如果所属 ViewModel 未注册，则抛出异常。
  /// Returns the owner ViewModel instance.
  /// 返回所属 ViewModel 实例。
  BaseVm getOwnerVm() {
    if (_ownerVm == null) {
      throw Exception('Owner ViewModel is not registered');
    }
    return _ownerVm!;
  }

  /// Notifies listeners through the owner ViewModel.
  /// 通过所属 ViewModel 通知监听器
  ///
  /// Catches and logs any errors that occur during notification.
  /// 捕获并记录通知期间发生的任何错误。
  void notifyListeners() {
    try {
      getOwnerVm().notifyListeners();
    } catch (e) {
      // Log the error - consider using a proper logging framework
      // 记录错误 - 考虑使用适当的日志框架
      print('Error notifying listeners: $e');
    }
  }

  /// Clears the owner ViewModel reference.
  /// 清除所属 ViewModel 的引用
  ///
  /// Called when the sub-module is being disposed.
  /// 在子模块被销毁时调用。
  void onCleared() {
    _ownerVm = null;
  }
}
